import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * @lc app=leetcode.cn id=697 lang=java
 *
 * [697] 数组的度
 *
 * https://leetcode-cn.com/problems/degree-of-an-array/description/
 *
 * algorithms
 * Easy (50.02%)
 * Likes:    86
 * Dislikes: 0
 * Total Accepted:    9.7K
 * Total Submissions: 19.1K
 * Testcase Example:  '[1,2,2,3,1]'
 *
 * 给定一个非空且只包含非负数的整数数组 nums, 数组的度的定义是指数组里任一元素出现频数的最大值。
 *
 * 你的任务是找到与 nums 拥有相同大小的度的最短连续子数组，返回其长度。
 *
 * 示例 1:
 *
 *
 * 输入: [1, 2, 2, 3, 1]
 * 输出: 2
 * 解释:
 * 输入数组的度是2，因为元素1和2的出现频数最大，均为2.
 * 连续子数组里面拥有相同度的有如下所示:
 * [1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
 * 最短连续子数组[2, 2]的长度为2，所以返回2.
 *
 *
 * 示例 2:
 *
 *
 * 输入: [1,2,2,3,1,4,2]
 * 输出: 6
 *
 *
 * 注意:
 *
 *
 * nums.length 在1到50,000区间范围内。
 * nums[i] 是一个在0到49,999范围内的整数。
 *
 *
 */

// @lc code=start
class Solution {
    public int findShortestSubArray(int[] nums) {
        int[][] dp = new int[50000][2];
        int max = 0;
        List<Integer> list = null;
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++) {
            if(!map.containsKey(nums[i])) {
                map.put(nums[i], 1);
                dp[nums[i]][0] = i;
                dp[nums[i]][1] = i;
            } else {
                int key = nums[i];
                int value = map.get(key);
                map.put(key, ++value);
                dp[key][1] = i;
            }
            int cnt = map.get(nums[i]);
            if(max < cnt) {
                list = new ArrayList<>();
                max = cnt;
            }
            if(max == cnt) {
                list.add(nums[i]);
            }
        }
        int min = Integer.MAX_VALUE;
        for(int i : list) {
            min = Math.min(dp[i][1] - dp[i][0] + 1, min);
        }
        return min;
    }
}
// @lc code=end

